﻿#include <QVector>
#include "OperateNoiseSpectrogram.h"
#include "GUIFrame/MainWindow.h"
#include "GUIFrame/CentralWidget.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "GUIDialog/GUIPhyscisDialog/QwtCustomPlot.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsPostData.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5LoadCase.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5DataSet.hpp"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Constants.h"
#include "FITK_Component/FITKAcousticsPostData/FITKAcousticsHDF5Frequencies.h"

#include "FITK_Kernel/FITKCore/FITKAbstractDataManager.hpp"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"

#include "GUIDialog/GUIPostDialog/GUIPostCurvePlotDialog.h"

namespace ModelOper
{
    OperateNoiseSpectrogram::OperateNoiseSpectrogram()
    {
        _xName = "Frequencies";
        initColorList();
        init();
    }
    QStringList OperateNoiseSpectrogram::getCaseNameList()
    {
        QStringList caseList;
        if (nullptr == _loadCaseManager)
        {
            return caseList;
        }
        // 得到工况列表
        int caseCount = _loadCaseManager->getDataCount();
        for (int i = 0; i < caseCount; i++)
        {
            auto caseObject = _loadCaseManager->getDataByIndex(i);
            if (caseObject == nullptr)
            {
                continue;
            }
            else
            {
                caseList.append(caseObject->getDataObjectName());
            }
        }
        return caseList;
    
    }

    QStringList OperateNoiseSpectrogram::getDataSetNameList(QString caseName)
    {
        QStringList resultList;
        auto selectLoadCase = _loadCaseManager->getDataByName(caseName);
        if (selectLoadCase == nullptr) return resultList;
        auto subSysManager = selectLoadCase->getFITKAcousticsHDF5ObjectChildManager();
        if (subSysManager == nullptr) return resultList;
        //子系统下的所有节点
        int childNodeCount = subSysManager->getDataCount();

        for (int i = 0; i < childNodeCount; i++)
        {
            auto subSystemoObject = subSysManager->getDataByIndex(i);
        }
        auto subSystemoObject = subSysManager->getDataByName(_subSystemName);
        if (subSystemoObject == nullptr) return resultList;

        auto dataObjectManager = subSystemoObject->getFITKAcousticsHDF5ObjectChildManager();
        if (dataObjectManager == nullptr) return resultList;
        int dataSetCount = dataObjectManager->getDataCount();
        for (int i = 0; i < dataSetCount; i++)
        {
            resultList.append(dataObjectManager->getDataByIndex(i)->getDataObjectName());
        }
        return resultList;
    }

    QString OperateNoiseSpectrogram::getTickSystemType(QString objectname)
    {
        QString value;
        if (_emitter->objectName() == "actionSemi_infiniteFluidNoise")
        {
            value = "SIFs";
        }
        else
        {
            value = "SubSystems";
        }
        return value;
    }

    QList<QVector<QPointF> > OperateNoiseSpectrogram::getCurvePoint(QString xName, QList<QString> listY)
    {
        QList<QVector<QPointF> > list;
        if (true != _colHashdata.contains(xName))
        {
            return list;
        }
        QVector<float> listX = _colHashdata[xName];

        for (auto key : listY)
        {
            if (true != _colHashdata.contains(key))
            {
                return list;
            }

            QVector<QPointF> listP;
            QVector<float> listV = _colHashdata[key];
            for (int i = 0; i < listX.size(); i++)
            {
                listP << QPointF(listX[i], listV[i]);
            }
            list << listP;
        }
        return list;
    }

    bool OperateNoiseSpectrogram::loadXData()
    {
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        //获取constant节点
        auto constantManager = postData->getFITKAcousticsHDF5Constants();
        if (constantManager == nullptr) return false;
        //获取频率数据
        auto frequencies = constantManager->getFITKAcousticsHDF5Frequencies();
        if (frequencies == nullptr) return false;
        auto frequenciesDatasetManager = frequencies->getFITKAcousticsHDF5DataSetManager();
        if (frequenciesDatasetManager == nullptr) return false;
        int freDataSetCount = frequenciesDatasetManager->getDataCount();
        //获取x轴频率数据
        for (int i = 0; i < freDataSetCount; i++)
        {
            auto dataSetObject = frequenciesDatasetManager->getDataByIndex(i);
            //获取数据项名称
            QString datasetName = dataSetObject->getDataObjectName();
            std::vector<float> dataSetVec = dataSetObject->getValues().value(0);
            QVector<float> xvec;
            for (int i = 0; i < dataSetVec.size(); i++)
            {
                xvec.append(dataSetVec.at(i));
            }
            _colNameList.append(_xName);
            _rowCount = dataSetVec.size();
            _colHashdata.insert(_xName, xvec);
        }
        return true;
    }

    void OperateNoiseSpectrogram::init()
    {
        _colHashdata.clear();
        _colNameList.clear();
        _yList.clear();
        _mainWindow= dynamic_cast<GUI::MainWindow *>(FITKAPP->getGlobalData()->getMainWindow());
        Acoustics::FITKAcousticsPostData* postData = FITKAPP->getGlobalData()->getPostData<Acoustics::FITKAcousticsPostData>();
        //获取loadcase下节点数据
        _loadCaseManager = postData->getFITKAcousticsHDF5LoadCaseManager();
    }

    void OperateNoiseSpectrogram::initColorList()
    {
        _colorList.append(Qt::blue);
        _colorList.append(Qt::red);
        _colorList.append(Qt::darkGray);
        _colorList.append(Qt::darkRed);
        _colorList.append(Qt::magenta);
        _colorList.append(Qt::darkMagenta);
        _colorList.append(Qt::blue);
        _colorList.append(Qt::darkBlue);
        _colorList.append(Qt::cyan);
        _colorList.append(Qt::darkCyan);
        _colorList.append(Qt::yellow);
        _colorList.append(Qt::darkYellow);
    }

    QList<Acoustics::FITKAbstractSEASubSys*>  OperateNoiseSpectrogram::getDataSetNameByType(QString objectname)
    {
        QList<Acoustics::FITKAbstractSEASubSys*> list;
        //获取离散数据
        Acoustics::FITKAcousticsDiscModel* discModel = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discModel)return list;
        //获取SEA点数据
        Acoustics::FITKAcousticsSEAModel* seaModel = discModel->getSEAModel();
        if (!seaModel) return list;
        //获取数据管理器
        Acoustics::FITKAcousticsSEASubSysManager *dataManager = seaModel->getSEASubSysManager();
        if (!dataManager)return list;

        int count = dataManager->getDataCount();
        for (int i = 0; i < count; i++)
        {
            Acoustics::FITKAbstractSEASubSys* subSys = dataManager->getDataByIndex(i);
            if (!subSys) continue;
            //根据类型 获取  可视化显示对象名称
            if (objectname =="actionNoiseSpectrogramResult" && subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEACavity)  //声腔
            {
                //获取所有声腔名称集合
               list.append(subSys);
            }
            else if (objectname == "actionVibrancySpectrogramResult") //梁板
            {
                if (subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEAFlatPlate ||
                    subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEABeam ||
                    subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEADoublyCurvedShell ||
                    subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEASinglyCurvedShell ||
                    subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEACylinderShell)
                {
                    //获取所有SEA板及梁名称集合
                    list.append(subSys);
                }
            }
            else if (objectname == "actionSemi_infiniteFluidNoise") //半无限流体
            {
                if (subSys->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid)
                {
                    //获取半无限名称集合
                    list.append(subSys);
                }
            }
        }
        return list;
    }

    void OperateNoiseSpectrogram::changeCaseSlot(QString caseName, QString dataSetName)
    {
        loadCaseData(caseName, dataSetName,_subSystemType);
        refreshData();
    }

    bool OperateNoiseSpectrogram::loadCaseData(QString caseName, QString datasetName, QString dataName)
    {
        _colNameList.clear();
        _yList.clear();
        loadXData();
        // 得到工况下的数据
        auto selectLoadCase = _loadCaseManager->getDataByName(caseName);
        if (!selectLoadCase) return false;
        //获取子系统下的数据项名
        auto subSysManager = selectLoadCase->getFITKAcousticsHDF5ObjectChildManager();
        if (subSysManager == nullptr) return false;
        auto loadCaseChild = subSysManager->getDataByName(dataName);
        if (loadCaseChild == nullptr) return false;

        auto dataObjectManager = loadCaseChild->getFITKAcousticsHDF5ObjectChildManager();
        if (dataObjectManager == nullptr) return false;
        auto dataSetObject = dataObjectManager->getDataByName(datasetName);
        if (dataSetObject == nullptr) return false;
        auto datasetManager = dataSetObject->getFITKAcousticsHDF5DataSetManager();
        if (datasetManager == nullptr) return false;
        int datasetCount = datasetManager->getDataCount();
        for (int i = 0; i < datasetCount; i++)
        {
            auto dataSetObject = datasetManager->getDataByIndex(i);
            //某个数据节点的名称，不是组名
            QString datasetName = dataSetObject->getDataObjectName();
            int datacount = dataSetObject->getValues().count();
            if (datacount == 0) continue;
            std::vector<float> datavec = dataSetObject->getValues().value(0);
            QVector<float> tempvec;
            for (int i = 0; i < datavec.size(); i++)
            {
                tempvec.append(datavec.at(i));
            }
            //保存数据项列表
            _colHashdata.insert(datasetName, tempvec);
            _colNameList.append(datasetName);
            _yList.append(datasetName);
        }
        return true;
    }

    //取子系统下的数据集列表
    QStringList OperateNoiseSpectrogram::getSelectDataSetList()
    {
        QStringList resultList;
        QList<Acoustics::FITKAbstractSEASubSys*> listSEASubSys = getDataSetNameByType(_emitter->objectName());
        int count = listSEASubSys.count();
        for (int i = 0; i < count; i++)
        {
            Acoustics::FITKAbstractSEASubSys* item = listSEASubSys.at(i);
            QString itemName = item->getDataObjectName();
            if (item->getSEASubSysType() == Acoustics::FITKAbstractSEASubSys::SEASemiIInfiniteFluid)
            {
                resultList.append(itemName);
            }
            else
            {
                resultList.append(itemName);
            }
        }
        return resultList;
    }
    
    bool OperateNoiseSpectrogram::execGUI()
    {
        //if (_emitter == nullptr)return false;
        //GUI::GUIPostCurvePlotDialog* dialog = new GUI::GUIPostCurvePlotDialog(this, FITKAPP->getGlobalData()->getMainWindow());
        //dialog->init(_emitter->objectName());
        //dialog->show();
        if (_emitter==nullptr)
        {
            return false;
        }
        init();
        QString datasetName;
        QString loadCaseName;
        QStringList _selectDataSetList = getSelectDataSetList();
        //获取第一个数据集成
        if (_selectDataSetList.count() > 0)
        {
            datasetName = _selectDataSetList.at(0);
        }
        //获取第一个工况名
        QStringList caseNameList = getCaseNameList();
        if (caseNameList.size() > 0)
        {
            loadCaseName = caseNameList.at(0);
        }
        _subSystemType = getTickSystemType(_emitter->objectName());
        loadCaseData(loadCaseName, datasetName, _subSystemType);
        _curveDialog = new GUI::GUICurvePlotDialog(_mainWindow);
        _curveDialog->setCaseNames(caseNameList, _selectDataSetList);
        connect(_curveDialog, SIGNAL(caseChangedSignal(QString, QString)), this, SLOT(changeCaseSlot(QString, QString)));
        refreshData();
        _curveDialog->exec();
        return true;
    }

    bool OperateNoiseSpectrogram::execProfession()
    {
        return true;
    }

    bool OperateNoiseSpectrogram::refreshData()
    {
        if (_curveDialog == nullptr) return false;
        _curveDialog->clearCurves();
        if (_colHashdata.size() == 0) return false;
        //将获取到曲线数据列表添加到绘制接口
        for (int i=0;i<_yList.count();i++)
        {
            QVector<float> xvec = _colHashdata.value(_xName);
            QVector<float> yvec = _colHashdata.value(_yList.at(i));
            _curveDialog->addCurve(xvec,yvec,_colorList[i % _colorList.size()], _yList.at(i));
        }
        //刷新表格数据
        _curveDialog->loadTableData(_colHashdata, _colNameList,_rowCount);
        return true;
    }

}
